/**
 * This is a class to handle marketPlace
 * @author Code Traders
 * @version 1.0
 */
public class MarketPlace {
	
	/**
	 * current planet
	 */
	private Planet currentPlanet;
	
	/**
	 * current ship
	 */
	private final Ship currentShip;
	
	/**
	 * array holding the list of ship's items
	 */
	private final int[] shipItem;
	
	/**
	 * current error value
	 */
	private int error = -1;
	
	/** for TWO **/
	private static final int TWO = 2;
	
	/** for THREE **/
	private static final int THREE = 3;
	
	/** for FOUR **/
	private static final int FOUR = 4;
	
	/** for FIVE **/
	private static final int FIVE = 5;

	/** for SIX **/
	private static final int SIX = 6;

	/**
	 * This is a constructor for MarketPlace
	 *
	 */
	public MarketPlace() {
		final Ship s = (Ship) Singleton.INSTANCE.get("ship");
		this.currentPlanet = s.getCurrentPlanet();
		this.currentShip = s;
		this.shipItem = s.getGoods();
	}
	
	/**
	 * This is a constructor for MarketPlace
	 * ++ to be used later for the MarketPlace between two Ships
	 * 
	 * @param s1 the first current Ship
	 * @param s2 the second current Ship
	 */
	public MarketPlace(Ship s1, Ship s2) {
		this.currentShip = s1;
		this.shipItem = s1.getGoods();
	}
	
	/**
	 * This method is to buy goods, store goods, and calculate money.
	 * 
	 * @param g Goods to buy
	 * @param n number of Goods to buy
	 * @return true if successfully purchased, false otherwise
	 */
	public boolean canBuy(Goods g, int n) {
		if (!currentShip.isCargoSpaceAvailable(n)) {
			error = 1;
			return false;
		} else if (!currentPlanet.getGoods()[g.ordinal()].isAvailableToBuy()) {
			error = TWO;
			return false;
		} else if (currentPlanet.getGoods()[g.ordinal()].getAmount() < n) {
			error = THREE;
			return false;
		} else if (currentShip.getMoney() <
				currentPlanet.getGoods()[g.ordinal()].getPrice() * n) {
			error = FOUR;
			return false;
		} else {
			error = -1;
		}
		currentPlanet.getGoods()[g.ordinal()].decAmount(n);
		currentShip.addGoods(g, n);
		currentShip.subtractMoney(currentPlanet.getGoods()[g.ordinal()].getPrice() * n);
		return true;
	}
	
	/**
	 * This method is for selling goods and to store goods and calculate money.
	 * 
	 * @param g Goods to sell
	 * @param n number of Goods to sell
	 * @return true if successfully sold, false otherwise
	 */
	public boolean canSell(Goods g, int n) {
		if (!currentPlanet.getGoods()[g.ordinal()].isAvailableToSell()) {
			error = FIVE;
			return false;
		} else if (shipItem[g.ordinal()] < n) {
			error = SIX;
			return false;
		} else {
			error = -1;
		}
		currentPlanet.getGoods()[g.ordinal()].incAmount(n);
		currentShip.removeGoods(g, n);
		currentShip.addMoney(currentPlanet.getGoods()[g.ordinal()].getPrice() * n);
		return true;
	}
	
	/**
	 * To get currentShip
	 * 
	 * @return the current Ship
	 */
	public Ship getShip() {
		return this.currentShip;
	}
	
	/**
	 * To get currentPlanet
	 * 
	 * @return the current Planet
	 */
	public Planet getPlanet() {
		return this.currentPlanet;
	}
	
	/**
	 * To get the array of goods
	 * 
	 * @return the current Goods of the Planet
	 */
	public Goods[] getGoods() {
		return currentPlanet.getGoods();
	}
	
	/**
	 * To handle errorMessage.
	 * 
	 * @return appropriate message.
	 */
	public String getErrorMsg() {
		switch (error) {
		case 1:
			return "There is not enough cargo space available in the ship";
		case TWO:
			return "The good is not available buy right now";
		case THREE:
			return "There is not enough good left in the planet";
		case FOUR:
			return "There is not enough money to buy the good";
		case FIVE:
			return "The good is not available to sell right now";
		case SIX:
			return "There is not enough good left in the ship";
		case -1:
			return "No Error";
		default:
			return "Invalid Error";
		}
	}

	/**
	 * This is a toString method.
	 * @return tostring.
	 */
	@Override
	public String toString() {
		return super.toString();
	}
}
